/**
 * 
 */
package com.xbang.attendance.entity.stock;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Transient;

import com.xbang.attendance.entity.order.DeliveryDetails;
import com.xbang.attendance.entity.order.DeliveryOrder;
import com.xbang.attendance.entity.order.PurchaseOrder;
import com.xbang.attendance.entity.product.Product;
import com.xbang.attendance.entity.system.Warehouse;
import com.xbang.attendance.security.support.SecurityUserHolder;

import enumeration.InventoryOperation;

/**
 * @author dev.zhang 仓储出入库记录
 */
@Entity
public class InventoryRecord implements Serializable {

	private static final long serialVersionUID = 245569003399151142L;

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private Integer id;
	/** Sales Order NO 编号 */
	private String poNumber;

	private Date salesOrderDate;

	/** 产品 */
	@ManyToOne(cascade = { CascadeType.MERGE }, targetEntity = Product.class)
	@JoinColumn(name = "product_id")
	private Product product;

	/** 仓库 */
	@ManyToOne(cascade = { CascadeType.MERGE }, targetEntity = Warehouse.class)
	@JoinColumn(name = "warehouse_id")
	private Warehouse warehouse;
	
	/**备份仓库 */
	@ManyToOne(cascade = { CascadeType.MERGE }, targetEntity = Warehouse.class)
	@JoinColumn(name = "ware_id")
	private Warehouse ware;
	
	@ManyToOne(cascade = CascadeType.MERGE, fetch = FetchType.LAZY, targetEntity = DeliveryDetails.class)
	@JoinColumn(columnDefinition = "deliveryDetails", referencedColumnName = "id")
	private DeliveryDetails deliveryDetails;

	@ManyToOne(cascade = CascadeType.MERGE, fetch = FetchType.LAZY, targetEntity = DeliveryOrder.class)
	@JoinColumn(columnDefinition = "delivryOrder", referencedColumnName = "id")
	private DeliveryOrder deliveryOrder;

	@ManyToOne(cascade = CascadeType.MERGE, fetch = FetchType.LAZY, targetEntity = Inventory.class)
	@JoinColumn(columnDefinition = "inventory", referencedColumnName = "id")
	private Inventory inventory;

	/** 产品数量 */
	private BigDecimal amount;

	/** 操作类型 in : 入库 、 out ：出库 */
	@Enumerated(EnumType.STRING)
	private InventoryOperation lastInventoryOperation;

	/** 操作人 */
	private String operationer;

	/** 是否完全匹配 */
	@Column(name = "exact_match")
	@org.hibernate.annotations.Type(type = "yes_no")
	private boolean exactMatch;

	/** 已匹配数量 */
	private BigDecimal matchAmount;

	/** 操作日期 */
	private Date operationDate;

	
	/**是否已经补过货了,只是针对未补货的*/
	@Column(name = "is_add_product")
	@org.hibernate.annotations.Type(type = "yes_no")
	private boolean addProduct = false;
	
	/**为了根据订单来补货*/
	@ManyToOne(cascade = CascadeType.MERGE, fetch = FetchType.LAZY, targetEntity = PurchaseOrder.class)
	@JoinColumn(columnDefinition = "purchaseOrder", referencedColumnName = "id")
	private PurchaseOrder purchaseOrder;
	
	private Date addProductDate;
	

 


	// //////////
	// ////以下信息是为了勾画前台写的属性
	// /////////////////
	@Transient
	private boolean total = false;

	public String getInventoryOperationDislpaly() {
		return this.lastInventoryOperation.getAliseName();
	}

	/**
	 * @param purchaseOrder
	 * @param warehouse
	 * @param deliveryDetails
	 * @param inventoryRecord
	 */
	public InventoryRecord initInventoryRecord(PurchaseOrder purchaseOrder, Warehouse warehouse, DeliveryDetails deliveryDetails) {
		this.setWarehouse(warehouse);
		this.setPoNumber(purchaseOrder.getOrderNumber());
		this.setPurchaseOrder(purchaseOrder);
		this.setAmount(deliveryDetails.getProductNumber());
		this.setOperationer(SecurityUserHolder.getCurrentUser().getName());
		this.setProduct(deliveryDetails.getProduct());
		this.setLastInventoryOperation(InventoryOperation.OUT);
		this.setOperationDate(new Date());
		this.setExactMatch(false);
		this.matchAmount = new BigDecimal(0);
		return this;
	}

	public InventoryRecord initialInventoryRecord(Inventory inventory, InventoryOperation inventoryOperation, BigDecimal amount, String operationer) {

		this.setWarehouse(inventory.getWarehouse());
		this.setProduct(inventory.getProduct());
		this.setInventory(inventory);
		this.setAmount(amount);
		this.setOperationer(operationer);
		this.setOperationDate(new Date());
		this.setLastInventoryOperation(inventoryOperation);
		if (inventoryOperation.equals(InventoryOperation.REPLENISHMENT)) {
			this.setExactMatch(true);
		} else {
			this.setExactMatch(false);
			this.matchAmount = new BigDecimal(0);
		}

		return this;
	}

	public InventoryRecord initialInventoryRecord(Warehouse warehouse, Product product, InventoryOperation inventoryOperation, BigDecimal amount,
			String operationer) {

		this.setWarehouse(warehouse);
		this.setProduct(product);
		this.setAmount(amount);
		this.setOperationer(operationer);
		this.setOperationDate(new Date());
		this.setLastInventoryOperation(inventoryOperation);
		if (inventoryOperation.equals(InventoryOperation.REPLENISHMENT)) {
			this.setExactMatch(true);
			this.matchAmount = amount;
		} else {
			this.setExactMatch(false);
			this.matchAmount = new BigDecimal(0);
		}

		return this;
	}

	/**
	 * @return the id
	 */
	public Integer getId() {
		return id;
	}

	/**
	 * @param id
	 *            the id to set
	 */
	public void setId(Integer id) {
		this.id = id;
	}

	/**
	 * @return the product
	 */
	public Product getProduct() {
		return product;
	}

	
	
	public boolean isAddProduct() {
		return addProduct;
	}

	public void setAddProduct(boolean addProduct) {
		this.addProduct = addProduct;
	}

	/**
	 * @param product
	 *            the product to set
	 */
	public void setProduct(Product product) {
		this.product = product;
	}

	/**
	 * @return the warehouse
	 */
	public Warehouse getWarehouse() {
		return warehouse;
	}

	/**
	 * @param warehouse
	 *            the warehouse to set
	 */
	public void setWarehouse(Warehouse warehouse) {
		this.warehouse = warehouse;
	}

	/**
	 * @return the amount
	 */
	public BigDecimal getAmount() {
		return amount;
	}

	/**
	 * @param amount
	 *            the amount to set
	 */
	public void setAmount(BigDecimal amount) {
		this.amount = amount;
	}

	/**
	 * @return the lastInventoryOperation
	 */
	public InventoryOperation getLastInventoryOperation() {
		return lastInventoryOperation;
	}

	/**
	 * @param lastInventoryOperation
	 *            the lastInventoryOperation to set
	 */
	public void setLastInventoryOperation(InventoryOperation lastInventoryOperation) {
		this.lastInventoryOperation = lastInventoryOperation;
	}

	/**
	 * @return the operationer
	 */
	public String getOperationer() {
		return operationer;
	}

	/**
	 * @param operationer
	 *            the operationer to set
	 */
	public void setOperationer(String operationer) {
		this.operationer = operationer;
	}

	/**
	 * @return the operationDate
	 */
	public Date getOperationDate() {
		return operationDate;
	}

	/**
	 * @param operationDate
	 *            the operationDate to set
	 */
	public void setOperationDate(Date operationDate) {
		this.operationDate = operationDate;
	}

	/**
	 * @return the poNumber
	 */
	public String getPoNumber() {
		return poNumber;
	}

	/**
	 * @param poNumber
	 *            the poNumber to set
	 */
	public void setPoNumber(String poNumber) {
		this.poNumber = poNumber;
	}

	/**
	 * @return the deliveryDetails
	 */
	public DeliveryDetails getDeliveryDetails() {
		return deliveryDetails;
	}

	/**
	 * @param deliveryDetails
	 *            the deliveryDetails to set
	 */
	public void setDeliveryDetails(DeliveryDetails deliveryDetails) {
		this.deliveryDetails = deliveryDetails;
	}

	/**
	 * @return the deliveryOrder
	 */
	public DeliveryOrder getDeliveryOrder() {
		return deliveryOrder;
	}

	/**
	 * @param deliveryOrder
	 *            the deliveryOrder to set
	 */
	public void setDeliveryOrder(DeliveryOrder deliveryOrder) {
		this.deliveryOrder = deliveryOrder;
	}

	/**
	 * @return the matchAmount
	 */
	public BigDecimal getMatchAmount() {
		return matchAmount;
	}

	/**
	 * @param matchAmount
	 *            the matchAmount to set
	 */
	public void setMatchAmount(BigDecimal matchAmount) {
		this.matchAmount = matchAmount;
	}

	/**
	 * @return the exactMatch
	 */
	public boolean isExactMatch() {
		return exactMatch;
	}

	/**
	 * @param exactMatch
	 *            the exactMatch to set
	 */
	public void setExactMatch(boolean exactMatch) {
		this.exactMatch = exactMatch;
	}

	/**
	 * @return the inventory
	 */
	public Inventory getInventory() {
		return inventory;
	}

	/**
	 * @param inventory
	 *            the inventory to set
	 */
	public void setInventory(Inventory inventory) {
		this.inventory = inventory;
	}

	/**
	 * @return the total
	 */
	public boolean isTotal() {
		return total;
	}

	/**
	 * @param total
	 *            the total to set
	 */
	public void setTotal(boolean total) {
		this.total = total;
	}

	/**
	 * @return the salesOrderDate
	 */
	public Date getSalesOrderDate() {
		return salesOrderDate;
	}

	/**
	 * @param salesOrderDate
	 *            the salesOrderDate to set
	 */
	public void setSalesOrderDate(Date salesOrderDate) {
		this.salesOrderDate = salesOrderDate;
	}

	public PurchaseOrder getPurchaseOrder() {
		return purchaseOrder;
	}

	public void setPurchaseOrder(PurchaseOrder purchaseOrder) {
		this.purchaseOrder = purchaseOrder;
	}
	
	public Date getAddProductDate() {
		return addProductDate;
	}

	public void setAddProductDate(Date addProductDate) {
		this.addProductDate = addProductDate;
	}

	public String getAddProductFlagDisplayText(){
		if(this.addProduct)
			return "已补货";
		else 
			return "未补货 ";
	}
	/**备份仓库*/
	public Warehouse getWare() {
		return ware;
	}
	/**备份仓库*/
	public void setWare(Warehouse ware) {
		this.ware = ware;
	}
}
